package com.chen.gcode.fx.controllers;

import com.chen.gcode.models.PrintMode;
import com.chen.gcode.models.SpindleType;
import com.chen.gcode.utils.AlertUtil;
import com.chen.gcode.utils.GCodeGenerate;
import com.chen.gcode.utils.ImageUtils;
import com.chen.gcode.utils.Setting;
import io.netty.util.internal.StringUtil;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.ImageView;

import javafx.scene.image.Image;
import javafx.scene.input.DragEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.paint.Color;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Window;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import static com.chen.gcode.utils.ImageUtils.IMAGE_TYPE_BMP;

public class BMP2GCodeController  implements Initializable {

    @FXML
    private AnchorPane pane;

    @FXML
    private ImageView originImageView;

    @FXML
    private ImageView resultImageView;

    @FXML
    private TextField imagePathTextFiled;


    @FXML
    private TextField printWidthTextFiled;


    @FXML
    private TextField printHeightTextFiled;


    @FXML
    private Label printSizeTipLabel;

    @FXML
    private Label originPixLabel;

    @FXML
    private Label dstPixLabel;

    @FXML
    private RadioButton lineScanfRadioButton;

    @FXML
    private RadioButton quickScanfRadioButton;

    @FXML
    private RadioButton bestScanfRadioButton;

    @FXML
    private RadioButton sniRadioButton;

    @FXML
    private RadioButton cutRadioButton;

    @FXML
    private RadioButton blackModelRadioButton;


    @FXML
    private RadioButton grayModelRadioButton;



    @FXML
    private TextField powerTextFiled;
    @FXML
    private TextField speedTextFiled;

    @FXML
    private TextField pointSizeTextFiled;


    @FXML
    private TextField safeDistanceTextFiled;
    @FXML
    private TextField deepDistanceTextFiled;



    private double currentImageWidthPixel;
    private double currentImageHeightPixel;


    private double originImageWidthPixel;
    private double originImageHeightPixel;


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        printSizeTipLabel.setBackground(new Background(new BackgroundFill(Color.rgb(229,190,63),null,null)));

        TextFieldChangeListener<String> printWidthTextFiledListener = new TextFieldChangeListener<String>(printWidthTextFiled);
        printWidthTextFiled.textProperty().addListener(printWidthTextFiledListener);


        TextFieldChangeListener<String> printHeightTextFiledListener = new TextFieldChangeListener<String>(printHeightTextFiled);
        printHeightTextFiled.textProperty().addListener(printHeightTextFiledListener);

        ToggleGroup tg = new ToggleGroup();
        lineScanfRadioButton.setToggleGroup(tg);
        quickScanfRadioButton.setToggleGroup(tg);
        bestScanfRadioButton.setToggleGroup(tg);


        quickScanfRadioButton.setSelected(true);

        speedTextFiled.setText(Setting.getInstance().getSpeed());
        powerTextFiled.setText(Setting.getInstance().getPower());
        pointSizeTextFiled.setText(String.valueOf(Setting.getInstance().getPointSize()));

        deepDistanceTextFiled.setText(Setting.getInstance().getDeepDistance().trim());
        safeDistanceTextFiled.setText(Setting.getInstance().getSafeDistance().trim());


        ToggleGroup tg2 = new ToggleGroup();
        sniRadioButton.setToggleGroup(tg2);
        sniRadioButton.setSelected(true);
        cutRadioButton.setToggleGroup(tg2);


        ToggleGroup mo = new ToggleGroup();
        blackModelRadioButton.setToggleGroup(mo);
        blackModelRadioButton.setSelected(true);
        grayModelRadioButton.setToggleGroup(mo);
    }



    @FXML
    public void widthchange(){
        caculate();
    }

    @FXML
    public void heightchange(){
        caculate();
    }


    public void caculate(){

        if (currentImageWidthPixel*currentImageHeightPixel >0 && printWidthTextFiled.getText() != null && printWidthTextFiled.getText().length() >0 && printHeightTextFiled.getText() != null && printHeightTextFiled.getText().length() >0){
            Double dstWidth = Double.valueOf(printWidthTextFiled.getText());
            Double dstHeight = Double.valueOf(printHeightTextFiled.getText());

//            BigDecimal dstWidthN = new BigDecimal(printWidthTextFiled.getText());
//            BigDecimal dstHeightN = new BigDecimal(printHeightTextFiled.getText());
//
//            Float pointSize = Setting.getInstance().getPointSize();
//            BigDecimal pointN = new BigDecimal(pointSize);


            double rec_w = dstWidth/Setting.getInstance().getPointSize();
            double rec_h = dstHeight/Setting.getInstance().getPointSize();
            BigDecimal dstWidthN = new BigDecimal(rec_w);
            BigDecimal dstHeightN = new BigDecimal(rec_h);

            double w = dstWidthN.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

            double h = dstHeightN.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();


            if (rec_h<dstHeight || rec_w<dstWidth){
                printSizeTipLabel.setText("推荐原图分辨率大于："+w+" X "+h);
            }else {
                printSizeTipLabel.setText("原图最佳尺寸："+w+" X "+ h);
            }
        }
    }

    @FXML
    public void update(ActionEvent e){

        String path =  imagePathTextFiled.getText().trim();
        File file = new File(path);

        if (file==null || !file.exists()){
            AlertUtil.alert("提示","图片不存在,请选择图片");
            return;
        }
        int wpix =   getDstImageWidthPixel();
        int hpix =   getDstImageHeightPixel();

        String suffix = path.substring(path.lastIndexOf("."));
        String dir = file.getParent();
        String tempPath = dir + File.separator + "temp"+suffix;



        ImageUtils.gray(path,tempPath);
        ImageUtils.scale2(tempPath,tempPath,getDstImageHeightPixel(),getDstImageWidthPixel(),true);
        dstPixLabel.setText(getDstImageWidthPixel()+" X "+getDstImageHeightPixel());
        //压缩到适合的尺寸
        Image image = new Image("file:"+tempPath);

        String bitmapPath = dir + File.separator + "temp.bmp";
        ImageUtils.convert(tempPath,IMAGE_TYPE_BMP,bitmapPath);







//        GCodeGenerate gCodeGenerate = new GCodeGenerate();
//        gCodeGenerate.updateToBlack(bitmapPath,"/Users/king/Downloads/12.bmp");

//        gCodeGenerate.medianFiltering(bitmapPath,"/Users/king/Downloads/13ss.bmp");



        resultImageView.setImage(image);
        save(e);

        if (e != null){
            AlertUtil.alert("提示","更新成功");
        }



    }



    @FXML
    public void openLastDir(ActionEvent e){
        File file = new File(Setting.getInstance().getLastFileDir().trim());
        try {
            if (file != null && file.exists())
                Desktop.getDesktop().open(file);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @FXML
    public void onclick(ActionEvent e){

        FileChooser fileChooser=new FileChooser();

        if (Setting.getSingleton().getLastFileDir()!= null && new File(Setting.getSingleton().getLastFileDir()).exists()){
            fileChooser.setInitialDirectory(new File(Setting.getSingleton().getLastFileDir()));
        }
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("图片类型", "*.bmp","*.png","*.jpg","*.jpeg"),
                new FileChooser.ExtensionFilter("所有类型", "*.*")
        );
        File file = fileChooser.showOpenDialog(pane.getScene().getWindow());
        select(file);

    }

    public void select(File file){
        if (file != null){
            Setting.getSingleton().setLastFileDir(file.getParent());
            Setting.getSingleton().save();

            String path = file.getPath();//选择的文件夹路径
            Image image = new Image("file:"+path);
            currentImageWidthPixel = image.getWidth();
            currentImageHeightPixel = image.getHeight();

            originImageWidthPixel = image.getWidth();
            originImageHeightPixel = image.getHeight();

            originPixLabel.setText(currentImageWidthPixel+" X "+currentImageHeightPixel);
            originImageView.setImage(image);
            imagePathTextFiled.setText(path);
            printWidthTextFiled.setText(String.valueOf(currentImageWidthPixel*Setting.getInstance().getPointSize()));
            printHeightTextFiled.setText(String.valueOf(currentImageHeightPixel*Setting.getInstance().getPointSize()));
            caculate();
        }
    }


    private int getDstImageWidthPixel(){
        Double dstWidth = Double.valueOf(printWidthTextFiled.getText());
        Double dstHeight = Double.valueOf(printHeightTextFiled.getText());
        double rec_w = dstWidth/Setting.getInstance().getPointSize();
        double rec_h = dstHeight/Setting.getInstance().getPointSize();
        BigDecimal dstWidthN = new BigDecimal(rec_w);
        BigDecimal dstHeightN = new BigDecimal(rec_h);

        double w = dstWidthN.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

        return Integer.parseInt(new java.text.DecimalFormat("0").format(w));
    }


    private int getDstImageHeightPixel(){
        Double dstWidth = Double.valueOf(printWidthTextFiled.getText());
        Double dstHeight = Double.valueOf(printHeightTextFiled.getText());
        double rec_w = dstWidth/Setting.getInstance().getPointSize();
        double rec_h = dstHeight/Setting.getInstance().getPointSize();
        BigDecimal dstWidthN = new BigDecimal(rec_w);
        BigDecimal dstHeightN = new BigDecimal(rec_h);

        double h = dstHeightN.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return Integer.parseInt(new java.text.DecimalFormat("0").format(h));
    }


    @FXML
    void getFile(DragEvent event) {
        List<File> files = event.getDragboard().getFiles();
        //获得文件
        File file = files.get(0);
        //之后的相关操作，获得文件路径等..
        select(file);
    }


    public void makeGCode(){
        String imagePath = imagePathTextFiled.getText().trim();
        File file = new File(imagePath);


        if (!file.exists()){
            AlertUtil.alert("提示","原图片不存在，请选择图片");
            return;
        }

        update(null);


        String suffix = imagePath.substring(imagePath.lastIndexOf("."));

        String dir = file.getParent();
        String bitmapPath = dir + File.separator + "temp.bmp";

        if (StringUtil.isNullOrEmpty(imagePath)){
            JOptionPane.showMessageDialog(null, "请选图片");
            return;
        }



        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        String date = df.format(new Date());

//        String savePath = Setting.getInstance().getSavePath().trim()+ File.separator+ date+ ".txt";
        String savePath = dir + File.separator + file.getName()+".nc";

        if (StringUtil.isNullOrEmpty(Setting.getInstance().getSavePath().trim())){
            JOptionPane.showMessageDialog(null, "请选保存路径");
            return;
        }

        boolean isLine =  lineScanfRadioButton.isSelected();

        boolean isQuick =  quickScanfRadioButton.isSelected();

        boolean isBest =  bestScanfRadioButton.isSelected();


        String mode = "line";

        if (isLine){
            mode = "line";
        }

        if (isQuick){
            mode = "quick";
        }

        if (isBest){
            mode = "best";
        }

        String spinder = null;
        if (sniRadioButton.isSelected()){
            spinder = SpindleType.SpindleType_Laser;
        }else {
            spinder = SpindleType.SpindleType_Extruders;
        }

        String mo = null;
        if (blackModelRadioButton.isSelected()){
            mo = PrintMode.PrintMode_Black;
        }else {
            mo = PrintMode.PrintMode_Gray;
        }

        GCodeGenerate gCodeGenerate = new GCodeGenerate();
        gCodeGenerate.setMode(mode);
        gCodeGenerate.setSpindleType(spinder);
        gCodeGenerate.setPrintMode(mo);
        gCodeGenerate.generateBlack(bitmapPath,savePath);

        AlertUtil.alert("提示","已生成Gcode");
    }


    public void openDir(){
        File file = new File(Setting.getInstance().getSavePath().trim());
        try {
            if (file != null && file.exists())
            Desktop.getDesktop().open(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class TextFieldChangeListener<T> implements ChangeListener<T>{

        private TextField textField;

        public TextFieldChangeListener(TextField textField) {
            this.textField = textField;
        }

        @Override
        public void changed(ObservableValue<? extends T> observable, T oldValue, T newValue) {
            caculate();
        }
    }


    @FXML
    public void save(ActionEvent e){
        String deepDistance =  deepDistanceTextFiled.getText().trim();
        String safeDistance =  safeDistanceTextFiled.getText().trim();

        Float dstWidth = Float.valueOf(pointSizeTextFiled.getText());
        Setting.getInstance().setSpeed(speedTextFiled.getText());
        Setting.getInstance().setPower(powerTextFiled.getText());


        Setting.getInstance().setDeepDistance(deepDistance);
        Setting.getInstance().setSafeDistance(safeDistance);
        Setting.getInstance().setPointSize(dstWidth);
        Setting.getInstance().save();

    }

}
